package com.java.mall_imooc.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.java.mall_imooc.common.enums.ResultEnum;
import com.java.mall_imooc.common.exception.RRException;
import com.java.mall_imooc.common.utils.*;
import com.java.mall_imooc.config.JwtProperties;
import com.java.mall_imooc.entity.User;
import com.java.mall_imooc.form.UserRegisterForm;
import com.java.mall_imooc.mapper.UserDao;
import com.java.mall_imooc.service.UserService;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;


@Service("userService")
@AllArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {
    private JwtProperties jwtProperties;

    @Override
    public PageUtils queryPage(User user, Integer pageNum, Integer pageSize) {
        IPage<User> page = this.page(
                new Page<>(pageNum, pageSize),
                new QueryWrapper<User>() // 拼接查询条件
        );

        return new PageUtils(page);
    }

    @Override
    public R register(UserRegisterForm userRegisterForm) {
        // 校验用户名、邮箱是否重复
        Integer countByUsername = this.baseMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getUsername, userRegisterForm.getUsername()));
        if (countByUsername > 0) {
            return R.error(ResultEnum.USERNAME_EXISTS);
        }
        Integer countByEmail = this.baseMapper.selectCount(new LambdaQueryWrapper<User>().eq(User::getEmail, userRegisterForm.getEmail()));
        if (countByEmail > 0) {
            return R.error(ResultEnum.EMAIL_EXISTS);
        }
        String hashed = BCrypt.hashpw(userRegisterForm.getPassword(), BCrypt.gensalt());
        userRegisterForm.setPassword(hashed);
        User user = new User();
        BeanUtils.copyProperties(userRegisterForm,user);

        return this.baseMapper.insert(user) == 1 ? R.ok() : R.error(ResultEnum.ERROR);

    }

    @Override
    public R login(String username, String password) {
        // 通过username查询
        User user = this.baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (user == null || !BCrypt.checkpw(password, user.getPassword())) {
            return R.error(ResultEnum.USERNAME_OR_PASSWORD_ERROR);
        }

        // 校验密码boolean checkpw = BCrypt.checkpw(password, dbUser.getPassword()); 出于安全都返回'用户名或密码错误'
        if (!BCrypt.checkpw(password, user.getPassword())) {
            return R.error(ResultEnum.USERNAME_OR_PASSWORD_ERROR);
        }

        // 生成jwtToken
        JwtUserInfo jwtUserInfo = new JwtUserInfo();
        jwtUserInfo.setUserId(user.getId());
        jwtUserInfo.setUsername(user.getUsername());
        try {
            String token = JwtUtils.generateToken(jwtUserInfo, jwtProperties.getPrivateKey(), jwtProperties.getExpire());
            // 设置token到cookie
            CookieUtils.setCookie(ContextHolderUtils.getRequest(),ContextHolderUtils.getResponse(),jwtProperties.getCookieName(),token,jwtProperties.getCookieMaxAge());
            return R.ok();
        } catch (Exception e) {
            throw new RRException(ResultEnum.GEN_JWT_ERROR);
        }
    }

}